
Imports System
Imports System.Collections
Imports System.Data
Imports System.Data.SqlClient
Imports _2bMatesSite.Common

Namespace _2bMatesSite.BO
	''' <summary>
	''' 2bmates group bulletin message.
	''' </summary>
	Public Class GroupBulletinMessage
		Inherits BulletinMessage
		Protected groupID As Integer = -1
		Protected group As Group = Nothing

		Public Sub New(ByVal dr As SqlDataReader)
			MyBase.New(dr)
		End Sub

		Public Sub New(ByVal fromUID As Integer, ByVal toGroupID As Integer, ByVal subject As String, ByVal body As String)
			MyBase.New(fromUID, subject, body)
			Me.groupID = toGroupID
		End Sub

		Public Overloads Overrides ReadOnly Property MessageType() As Messages.MessageType
			Get
				Return Messages.MessageType.mtGroupBulletin
			End Get
		End Property

		Public Overloads Overrides ReadOnly Property Recipients() As ArrayList
			Get
				' - Recieved bulletins do not have recipients list
				' - Sent and new (just composed) bulletins have
				'		the list of friends of the sender as recipients
				If box = Messages.BoxType.btInbox Then
					Return New ArrayList()
				Else
					Return GetRecipients()
				End If
			End Get
		End Property

		Public ReadOnly Property GroupID() As Integer
			Get
				Return groupID
			End Get
		End Property

		Public ReadOnly Property Group() As Group
			Get
				If group = Nothing AndAlso groupID >= 0 Then
					group = Groups.GetGroupByID(groupID)
				End If
				Return group
			End Get
		End Property

		Public Overloads Overrides Sub Send()
			If messageID >= 0 Then
				Throw New MessageException("Can't send bulletins that are already sent.")
			End If

			Dim conn As SqlConnection = DBManager.GetUnmanagedConnection()
			Dim trans As SqlTransaction = conn.BeginTransaction()

			Try
				' Send the bulletin
				Send(trans)

				' Store the bulletin in the sender's outbox
				Insert(trans, -1, DateTime.Now)

				' Done
				trans.Commit()
			Catch generatedExceptionName As Exception
				trans.Rollback()
				Throw
			Finally
				conn.Close()
			End Try
		End Sub


		'
		' Private methods
		'

		Protected Overloads Overrides Sub Init(ByVal dr As SqlDataReader)
			messageID = dr.GetInt32(dr.GetOrdinal("ID"))

			subject = DBManager.GetNZString(dr, "Subject")
			body = DBManager.GetNZString(dr, "Body")

			senderUID = dr.GetInt32(dr.GetOrdinal("FromUID"))
			groupID = DBManager.GetNZInt32(dr, "ToGroupID")

			Dim ToUID As Integer = DBManager.GetNZInt32(dr, "ToUID")
			If ToUID > 0 Then
				rcptList.Add(ToUID)
			End If

			dateSent = dr.GetDateTime(dr.GetOrdinal("Date"))
			messageRead = dr.GetBoolean(dr.GetOrdinal("StatusRead"))
			messageDeleted = dr.GetBoolean(dr.GetOrdinal("StatusDeleted"))
		End Sub

		' Returns an array of user ID's
		Private Function GetRecipients() As ArrayList
			Dim res As New ArrayList()

			Dim grp As Group = Me.Group
			If grp <> Nothing Then
				Dim fromUID As Integer = SenderID
				Dim grpModerator As Integer = grp.Uid
				Dim grpMembers As GroupsUsers = grp.Members

				Dim senderIsModerator As Boolean = (fromUID = grpModerator)
				If senderIsModerator OrElse grpMembers.Contains(fromUID) Then
					' Only send messages if the sender is a) moderator or b) group member
					For Each gm As GroupMember In grpMembers
						If senderIsModerator Then
							' Sender is the moderator
							If gm.AcceptModeratorBulletin Then
								res.Add(gm.UserID)
							End If
ElseIf gm.AcceptMemberBulletin Then
							' Sender is a member, and the current group member
							' wants to recieve bulletins from other members
							res.Add(gm.UserID)
						End If
					Next
				End If
			End If

			Return res
		End Function

		Public Overloads Overrides Sub Save()
			If messageID < 0 Then
				Throw New MessageException("Can't update messages that are not yet sent.")
			End If
			Update()
		End Sub

		Public Overloads Overrides Sub Delete()
			Dim conn As SqlConnection = DBManager.GetUnmanagedConnection()

			Try
				Dim cmd As New SqlCommand("DELETE FROM GroupBulletins WHERE ID=@ID")
				cmd.Connection = conn
				cmd.Parameters.Add("@ID", messageID)
				cmd.ExecuteNonQuery()

				messageID = -1
			Finally
				conn.Close()
			End Try
		End Sub

		Protected Function Insert(ByVal trans As SqlTransaction, ByVal rcpt As Integer, ByVal [date] As DateTime) As Integer
			Dim conn As SqlConnection = trans.Connection

			Dim cmd As New SqlCommand("SaveGroupBulletin")
			cmd.CommandType = CommandType.StoredProcedure
			cmd.Connection = conn
			cmd.Transaction = trans

			PopulateCommand(cmd, rcpt)

			cmd.Parameters.Add("@FromUID", senderUID)
			cmd.Parameters.Add("@ToGroupID", groupID)
			DBManager.SetNZValue(cmd, "@ToUID", rcpt)
			cmd.Parameters.Add("@Date", [date])

			Dim paramID As SqlParameter = cmd.Parameters.Add("@ID", SqlDbType.Int)
			paramID.Direction = ParameterDirection.Output

			cmd.ExecuteNonQuery()

			Return DirectCast(paramID.Value, Integer)
		End Function

		Protected Sub Send(ByVal trans As SqlTransaction)
			Dim [date] As DateTime = DateTime.Now
			Dim sender As User = Me.Sender

			' Chache a hash of all the blockers of the sender
			Dim blockingUsers As UsersBlocked = sender.BlockingUsers
			Dim blockingUsersIDs As New Hashtable()
			For Each usr As User In blockingUsers
				blockingUsersIDs(usr.ID) = usr.ID
			Next

			' commented by Vesy :21.09.2005
			'Hashtable blockingUsersIDs = new Hashtable();
			'foreach( BlockedUser usr in sender.BlockingUsers )
			'	blockingUsersIDs[ usr.UserID ] = usr.UserID;

			' NOTE : it is important to call the virutal property instead the member variable directly,
			' so that descendatns may stand inbetween
			For Each rcpt As Integer In Recipients
				If blockingUsersIDs.Contains(rcpt) Then
					Continue For
					' Skip a blocking user
				End If

				' Send one to the recipient's inbox
				Insert(trans, rcpt, [date])
			Next

			' get group moderator
			Dim gm As User = Users.GetUserByID(group.Uid)

			If gm.EnableGroupEmailNotify Then
				GroupNotifications.SendNewGroupBulletinModeratorNotification(gm, groupID, Me.Sender)
			End If
		End Sub

		Protected Overloads Overrides Sub Update()
			Dim conn As SqlConnection = DBManager.GetUnmanagedConnection()

			Try
				Dim cmd As New SqlCommand(GetUpdateSQL())
				cmd.Connection = conn

				PopulateCommand(cmd)
				cmd.Parameters.Add("@ID", messageID)

				cmd.ExecuteNonQuery()
			Finally
				conn.Close()
			End Try
		End Sub

		Protected Overloads Overrides Function GetUpdateSQL() As String
			Dim sql As String = "UPDATE GroupBulletins" + Environment.NewLine
			sql += "SET" + Environment.NewLine
			sql += "" & Chr(9) & "Subject = @Subject," + Environment.NewLine
			sql += "" & Chr(9) & "Body = @Body," + Environment.NewLine
			sql += "" & Chr(9) & "StatusRead = @StatusRead," + Environment.NewLine
			sql += "" & Chr(9) & "StatusDeleted = @StatusDeleted " + Environment.NewLine
			sql += "WHERE" + Environment.NewLine
			sql += "" & Chr(9) & "ID = @ID" + Environment.NewLine

			Return sql
		End Function

		'	NOTE : the following params are not set
		'	@ID
		'	@FromUID
		'	@ToGroupID
		'	@ToUID
		'	@Date
		Protected Overridable Sub PopulateCommand(ByVal cmd As SqlCommand, ByVal rcpt As Integer)
			cmd.Parameters.Add("@Subject", subject)
			cmd.Parameters.Add("@Body", body)

			cmd.Parameters.Add("@StatusRead", messageRead)
			cmd.Parameters.Add("@StatusDeleted", messageDeleted)
		End Sub
	End Class
End Namespace






